/*
 * 练习题 2.42
 *
 * 写一个函数 div16，对于整数参数 x 返回 x/16 的值。你的函数不能使用除法、模运算、
 * 乘法、任何条件语句（if 或者 ?:）、任何比较运算符（例如 <、>或==）或任何循环。
 * 你可以假设数据类型 int 是 32 位长，使用补码表示，而右移是算术右移。
 */

/*
 * 这里用到了左移运算符，不知符不符合要求
 */
int div16(int x)
{
        int sign = (x & (1<<31)) >> 31; /* sign 的位级表示是全 0 或者全 1 */
        return (x + (sign & 0x0F)) >> 4;
}

/*
 * 书本的实现更加简洁优雅
 *
 * 这里唯一的挑战是不用任何测试或条件运算计算偏置值。我们利用了一个诀窍，表达式
 * x>>31 产生一个字，如果 x 是负数，这个字为全 1，否则为全 0.通过掩码屏蔽适当的位，
 * 我们就得到期望的偏置值。
 */
int book_div16(int x)
{
        /* Compute bias to be either 0 (x >= 0) or 15 (x < 0) */
        int bias = (x >> 31) & 0xF;
        return (x + bias) >> 4;
}
